﻿#pragma once
#include "CStrategyRenderCommon.h"

struct _stStrategyBorderD3DVertex
{
	float x, y, z;
	float u, v;
};

struct _stStrategyBorderVerticesInfo
{
	std::set<int>			setAreaIn;
	const _stProvinceInfo*	pAdjacentProvinceA = nullptr;
	const _stProvinceInfo*	pAdjacentProvinceB = nullptr;
	LPDIRECT3DVERTEXBUFFER9	pVB;			// 顶点缓冲区指针
	LPDIRECT3DINDEXBUFFER9	pIB;			// 索引缓冲区指针
	DWORD					dwVerticesNum;	// 顶点个数
	DWORD					dwIndicesNum;	// 索引个数
};

struct _stBorderInfo
{
	_stBorderInfo() = default;
	_stBorderInfo(const _stBorderInfo&) = default;
	D3DXVECTOR2 vec2;
};
struct _stAdjacentProvincePtrNdequeBorder
{
	_stAdjacentProvincePtrNdequeBorder(const _stProvinceInfo* p1, const _stProvinceInfo* p2) : pAdjacentProvince1(p1), pAdjacentProvince2(p2) {}
	std::deque<_stBorderInfo> dequeBorderBody;
	const _stProvinceInfo* pAdjacentProvince1 = nullptr;
	const _stProvinceInfo* pAdjacentProvince2 = nullptr;
};
typedef std::unordered_multimap<uint64_t, _stAdjacentProvincePtrNdequeBorder> _mapAllBorderBody;

struct _stSegment		// 线段
{
public:
	_stSegment(DWORD pos1, DWORD pos2)
	{
		if (pos1 < pos2)
		{
			posLess = pos1;
			posLarge = pos2;
		}
		else
		{
			posLess = pos2;
			posLarge = pos1;
		}
	}
	bool operator == (const _stSegment& st) const { return posLess == st.posLess && posLarge == st.posLarge; }
	bool operator < (const _stSegment& st) const
	{
		if (posLess < st.posLess)
		{
			return true;
		}
		else if (posLess == st.posLess)
		{
			return posLarge < st.posLarge;
		}
		return false;
	}

	DWORD GetPosLess() const { return posLess; }
	DWORD GetPosLarge() const { return posLarge; }
private:
	DWORD posLess;
	DWORD posLarge;
};
struct _stAdjacentProvincePtrNsetSegment
{
	std::set<_stSegment> setSegment;
	const _stProvinceInfo* pAdjacentProvince1 = nullptr;
	const _stProvinceInfo* pAdjacentProvince2 = nullptr;
};
typedef std::unordered_map<uint64_t, _stAdjacentProvincePtrNsetSegment> _mapAllBorderSegment;

class CStrategyProvinceBorder
{
public:
	CStrategyProvinceBorder();
	~CStrategyProvinceBorder();

	HRESULT OnCreateDevice(IDirect3DDevice9* pd3dDevice);
	HRESULT OnResetDevice(IDirect3DDevice9* pd3dDevice);
	void OnFrameMove(const D3DXMATRIXA16* pWorldViewProject, const D3DXVECTOR4* vCamLookAtDir);
	void OnFrameRender(IDirect3DDevice9* pd3dDevice, float fTime);
	void OnLostDevice();
	void OnDestroyDevice();

private:
	HRESULT CreateMeshWhenResetDevice(IDirect3DDevice9* pd3dDevice);	// 创建模型
	bool TraverseProvinceBorderSegment(_stRGB* pProvinceRGB, _mapAllBorderSegment& mapBorderPoint) const;		// 遍历省份颜色图 产生单位线段
	bool TransBorderSegment2Line(_mapAllBorderSegment& mapBorderSegment);		// 遍历单位线段 形成折线
	void TraverseSetSegment2FindNextPos(DWORD indexBegin, std::set<_stSegment>& setSegment, bool bPushFront, std::deque<_stBorderInfo>& dequeBorderBody) const;
	HRESULT BuildMesh(IDirect3DDevice9* pd3dDevice);
	inline float GetBorderWidth() const;
	float GetBorderHeight(float x, float y) const;

private:
	LPDIRECT3DVERTEXDECLARATION9	m_pDecl;	// 顶点声明接口
	LPD3DXEFFECT					m_pEffect;	// 效果接口

	_mapAllBorderBody				m_multimapAllBorder;		// 一个省份的颜色TODWORD来做key 因为有n条边 所以用multimap
	std::list<_stStrategyBorderVerticesInfo>		m_listBorderVerticInfo;

private:
	friend class CProgramDataMgr;
	bool CreateProvinceBorderInfo(_stRGB* pProvinceRGB);
};